using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using usm.SolDev.DataBase.DataObjects;
using System.Runtime.Remoting.Messaging;
using usm.SolDev.Common;
using usm.SolDev.DataBase.DataAccess;

namespace usm.SolDev.App
{
    /// <summary>
    ///     Save project to local file system or database repository
    /// </summary>
    public partial class SaveAsForm : usm.SolDev.UI.BaseForm
    {
        #region Private properties
        private ProjectDescriptor projectDescriptor;
        #endregion

        #region Constructors
        public SaveAsForm(ProjectDescriptor projectDescriptor)
        {
            InitializeComponent();
            this.projectDescriptor = projectDescriptor;
        }
        #endregion

        #region Form event handlers
        /// <summary>
        ///     Handle browse button click. Also check by default file System
        /// radiobutton.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            dlgSaveFile.FileName = String.Format("{0}.sde", projectDescriptor.Description);
            if (dlgSaveFile.ShowDialog() == DialogResult.OK)
            {
                projectDescriptor.LastEditTime = DateTime.Now;
                rbFileSystem.Checked = true;
            }
        }

        /// <summary>
        ///     Save button click handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            #region Generate GUID if not set (for new projects)
            if (projectDescriptor.Id == null || projectDescriptor.Id.Equals(Guid.Empty))
            {
                projectDescriptor.Id = Guid.NewGuid();
            }
            #endregion
            
            #region Set source
            if (rbFileSystem.Checked == true)
            {
                projectDescriptor.Origin = usm.SolDev.Common.Constants.Application.Origins.fromFile;
            }
            else
            {
                projectDescriptor.Origin = usm.SolDev.Common.Constants.Application.Origins.fromDatabase;
                projectDescriptor.Description = tbDescription.Text;
            }
            #endregion

            (new SaveProjectDelegate(SaveProject)).BeginInvoke(projectDescriptor, new AsyncCallback(SaveProjectCallBack), null);
            base.StartWaiting();
        }
        #endregion

        #region Save project logic
        /// <summary>
        ///     Execute the business logic of the save 
        /// </summary>
        /// <param name="projectDescriptor"></param>
        /// <returns></returns>
        private bool SaveProject(ProjectDescriptor projectDescriptor)
        {

            if (this.projectDescriptor.Origin == usm.SolDev.Common.Constants.Application.Origins.fromFile)
            {
                try
                {
                    this.projectDescriptor.SaveToFile(dlgSaveFile.FileName);
                    projectDescriptor.FilePath = dlgSaveFile.FileName;
                    return true;
                }
                catch (Exception ex)
                {
                    new SolDev.Common.SolDevException("Cannot save project", ex);
                    return false;
                }
            }
            else
            {
                return DataProvider.DataBase.SaveProjectToRepository(projectDescriptor);
            }
        }

        #endregion

        #region Operation complete delegates
        /// <summary>
        ///     Completion of save process
        /// </summary>
        /// <param name="projectDescriptor"></param>
        private delegate bool SaveProjectDelegate (ProjectDescriptor projectDescriptor);
        private void SaveProjectCallBack(IAsyncResult ar)
        {
            try
            {
                bool operationResult = ((SaveProjectDelegate)((AsyncResult)ar).AsyncDelegate).EndInvoke(ar);
                if (!IsDisposed && IsHandleCreated)
                {
                    BeginInvoke(new AfterOperationCompletedDelegate(AfterOperationCompleted), new object[] { operationResult});
                }
            }
            catch (Exception ex)
            {
                BeginInvoke(new AfterOperationCompletedDelegate(AfterOperationCompleted), new object[] {false});
                new SolDevException("Cannot complete save operation", ex);
            }
        }

        /// <summary>
        ///     Finalize save process and close the window
        /// </summary>
        /// <param name="success"></param>
        /// <param name="userInfoData"></param>
        private delegate void AfterOperationCompletedDelegate(bool success);
        private void AfterOperationCompleted(bool success)
        {
            base.EndWaiting();

            if (success == true)
            {
                DialogResult = DialogResult.OK;
            }
        }
        #endregion

        /// <summary>
        ///     Set focus on default control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveAsForm_Load(object sender, EventArgs e)
        {
            tbDescription.Text = projectDescriptor.Description;
            tbDescription.Focus();
        }
    }
}

